﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Security.Cryptography;
using System.Security.Policy;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
using System.Xml;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace PWMgr
{
    public partial class FormDe : Form
    {
        private const string COPYRIGHT = "Copyright © 2024 CloudC_Zh.All right reserved.";

        private const int SIZE = 24;
        private const int SLEEP_TIME = 100;
        private string pw;
        private string salt;
        private int count;
        private string filepath;
        private string savedir;
        public FormDe()
        {
            InitializeComponent();
            this.StartPosition = FormStartPosition.CenterScreen;
            pw = "";
            salt = "";
            savedir = "";
            filepath = "";
            label1.Text = COPYRIGHT;
        }

        private void labelfilepathde_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Multiselect = false;
            ofd.Title = "选择文件";
            ofd.Filter = "filEncryption文件(*.filEncryption)|*.filEncryption";
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                //FileInfo fileInfo = new FileInfo(ofd.FileName);
                filepath = ofd.FileName;
                labelfilepathde.Text = Path.GetFileName(ofd.FileName);
            }
        }

        private async void buttonSurede_Click(object sender, EventArgs e)
        {
            progressBarde.Minimum = 0;
            progressBarde.Maximum = 100;
            Progress<int> proc = new Progress<int>(v =>
            {
                progressBarde.Value = v;
            });
            await Task.Run(() => DecryptWork(proc));


        }

        private void DecryptWork(IProgress<int> proc)
        {
            #region 参数检查
            if (textpwde.Text.Equals(""))
            {
                MessageBox.Show("密码不能为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            if (textsaltde.Text.Equals(""))
            {
                MessageBox.Show("盐值不能为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            if (textcountde.Text.Equals(""))
            {
                MessageBox.Show("迭代次数不能为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            else
            {
                int.TryParse(textcountde.Text, out count);
                if (count <= 0)
                {
                    MessageBox.Show("迭代次数必须是大于0的整数！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                    return;
                }
            }
            if (labelfilepathde.Text.Equals("点击选择文件"))
            {
                MessageBox.Show("文件路径不能为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            if (labelsavepathde.Text.Equals("点击选择目录"))
            {
                MessageBox.Show("导出目录不能为空！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            if (!File.Exists(filepath))
            {
                MessageBox.Show("文件" + filepath + "不存在！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            if (!Directory.Exists(savedir))
            {
                MessageBox.Show("路径" + savedir + "不存在！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }

            #endregion
            splitContainerde.Enabled = false;
            #region 生成密钥
            proc.Report(0);
            labelShowde.Text = "生成密钥...";
            labelShowde.Refresh();
            Thread.Sleep(SLEEP_TIME);
            pw = textpwde.Text;
            salt = textsaltde.Text;
            //int itear = int.Parse(textcount.Text);
            Rfc2898DeriveBytes pbk = new Rfc2898DeriveBytes(pw, System.Text.Encoding.UTF8.GetBytes(salt), count);
            proc.Report(30);
            Thread.Sleep(SLEEP_TIME);
            byte[] pwbytes = pbk.GetBytes(SIZE);
            proc.Report(70);
            Thread.Sleep(SLEEP_TIME);
            string res = BitConverter.ToString(pwbytes).Replace("-", "");
            proc.Report(100);
            Thread.Sleep(SLEEP_TIME);
            #endregion

            #region 解密文件逻辑
            proc.Report(0);
            labelShowde.Text = "读取密文...";
            labelShowde.Refresh();
            Thread.Sleep(SLEEP_TIME);

            for (int i = 0; i < 30; i++)
            {
                proc.Report(i);
                Thread.Sleep(SLEEP_TIME / 10);
            }
            byte[] filebytes = File.ReadAllBytes(filepath);
            for (int i = 30; i < 100; i++)
            {
                proc.Report(i);
                Thread.Sleep(SLEEP_TIME / 5);
            }

            proc.Report(0);
            labelShowde.Text = "解密中...";
            labelShowde.Refresh();
            Thread.Sleep(SLEEP_TIME);
            byte[] resbyte = new byte[filebytes.Length];
            for (int i = 0, j = 0; i < filebytes.Length && j < pwbytes.Length;)
            {

                resbyte[i] = (byte)(pwbytes[j] ^ filebytes[i]);
                i++;
                j++;
                if (j == pwbytes.Length) j = 0;

                if (i == filebytes.Length * 0.1f)
                {
                    proc.Report(10);
                }
                else if (i == filebytes.Length * 0.2f)
                {
                    proc.Report(20);
                }
                else if (i == filebytes.Length * 0.3f)
                {
                    proc.Report(30);
                }
                else if (i == filebytes.Length * 0.4f)
                {
                    proc.Report(40);
                }
                else if (i == filebytes.Length * 0.5f)
                {
                    proc.Report(50);
                }
                else if (i == filebytes.Length * 0.6f)
                {
                    proc.Report(60);
                }
                else if (i == filebytes.Length * 0.7f)
                {
                    proc.Report(70);
                }
                else if (i == filebytes.Length * 0.8f)
                {
                    proc.Report(80);
                }
                else if (i == filebytes.Length * 0.9f)
                {
                    proc.Report(90);
                }
                else if (i == filebytes.Length)
                {
                    proc.Report(100);
                }
            }
            Thread.Sleep(SLEEP_TIME);
            proc.Report(0);
            labelShowde.Text = "导出明文...";
            labelShowde.Refresh();
            Thread.Sleep(SLEEP_TIME);
            FileStream ofs = new FileStream(Path.Combine(savedir, Path.GetFileNameWithoutExtension(filepath)), FileMode.Create);
            proc.Report(48);
            Thread.Sleep(SLEEP_TIME);
            ofs.Write(resbyte, 0, resbyte.Length);
            proc.Report(87);
            Thread.Sleep(SLEEP_TIME);
            ofs.Close();

            #endregion

            if (checkBoxdeletefilede.Checked)
            {
                //删除源文件
                File.Delete(filepath);
                //filepath = "";
                //labelfilepathde.Text = "点击选择文件";
            }
            proc.Report(100);
            Thread.Sleep(SLEEP_TIME*10);
            labelShowde.Text = "解密完成";
            labelShowde.Refresh();
            Thread.Sleep(SLEEP_TIME * 10);
            splitContainerde.Enabled = true;
        }

        private void labelsavepathde_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.FolderBrowserDialog dialog = new System.Windows.Forms.FolderBrowserDialog();
            dialog.Description = "请选择加密文件导出目录";
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                if (string.IsNullOrEmpty(dialog.SelectedPath))
                {
                    MessageBox.Show(this, "文件夹路径不能为空", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                    return;
                }
                labelsavepathde.Text = dialog.SelectedPath;
                savedir = dialog.SelectedPath;
            }
        }

        private void labelfilepath_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }
        private void labelfilepath_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (files.Length > 1)
            {
                MessageBox.Show("只能传入一个文件，多个文件请分批次或打包传入", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            else if (!Path.GetExtension(files[0]).Equals("filEncryption"))
            {

            }
            //labelShow.Text = files[0];
            filepath = files[0];
            labelfilepathde.Text = Path.GetFileName(filepath);
        }
        private void tableLayoutPanel1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                e.Effect = DragDropEffects.Copy;
            }
        }
        private void tableLayoutPanel1_DragDrop(object sender, DragEventArgs e)
        {
            string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
            if (files.Length > 1)
            {
                MessageBox.Show("只能传入一个文件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            string xmlpath = files[0];
            XmlDocument xmlDocument = new XmlDocument();
            try
            {
                xmlDocument.Load(xmlpath);
            }
            catch (XmlException ex)
            {
                MessageBox.Show("请传入可解析的xml文件", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly);
                return;
            }
            XmlNode root = xmlDocument.DocumentElement;
            salt = root.SelectSingleNode("salt").InnerText;
            count = int.Parse(root.SelectSingleNode("count").InnerText);
            textsaltde.Text = salt;
            textcountde.Text = count.ToString();
        }
    }
}
